package com.uam.core.lk.utils;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @author 祝展  token生成工具
 * @version 1.0
 * @description
 * @Date 2019/10/31 17:16
 **/
public class TokenGenerator {

    private static final  char[] table ={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

    private static Map<Character,Integer> tableMap =new HashMap();
    static {
        for (int i=0;i<table.length;i++){
            tableMap.put(table[i],i);
        }
    }

    /**
     * 随机填充字符串的取值范围
     */
    private static final String strGroup = "abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    /**
     * 生成的token长度
     */
    public static final int tokenLength = 64;

    /**
     * Description: 生成token
     * 规则：单位时间戳内为用户生成唯一UUID
     * 主要就是六部分：长度定义部分(定长2)，时间戳(定长13)，参数1，uuid(定长32)，随机填充，参数2
     *
     * @param  userId   用户ID
     * @param  paramId   参数ID
     * @return  java.lang.String
     * @date  2019/10/31 17:17 祝展
     */
    public static String createToken(Long userId,Long paramId) {
        String timestampStr = timeGen();
        String userIdStr = userIdGen(userId);
        String paramStr = "";
        if ( paramId != null ){
            paramStr = userIdGen(paramId);
        }
        String uuidStr = uuidGen();
        Integer userLength = userIdStr.length();
        Integer paramLength = paramStr.length();
        Character userCharacter = table[userLength];
        Character paramCharacter = table[paramLength];

        Integer randomLength = tokenLength - 2 - timestampStr.length()- userLength - uuidStr.length()  - paramLength;
        String randomStr = randomString(randomLength);

        String returnStr =null;
        if (paramId==null){
            returnStr =  ""+userCharacter + paramCharacter + timestampStr + userIdStr + uuidStr + randomStr;
        }else{
            returnStr =  ""+userCharacter + paramCharacter + timestampStr + userIdStr + uuidStr + randomStr + paramStr;
        }
        return returnStr;
    }

    /**
     * 功能描述:    解析token，参照生成规则反向解析
     * @Param  token
     * @Return   List<Long>
     * @Date  2019/10/31 17:18 祝展
     */
    public static List<Long> analysisToken(String token) {
        if ( StringUtils.isBlank(token) || token.length() < tokenLength) {
            return new ArrayList<>();
        }
        Integer userIdLength= tableMap.get( token.charAt(0));
        Integer paramIdLength= tableMap.get( token.charAt(1));

        int listLength =0;
        if (userIdLength !=0 ){
            listLength++;
        }
        if (paramIdLength !=0 ){
            listLength++;
        }
        List<Long> retList = new ArrayList<>(listLength);

        String userIdStr = token.substring(1+ 1 + 13, 1+ 1 + 13 + userIdLength);
        Long userId = Long.parseLong(userIdStr);
        retList.add(userId);
        if ( paramIdLength != 0 ){
            String paramIdStr = token.substring(tokenLength -paramIdLength , tokenLength);
            Long paramId = Long.parseLong(paramIdStr);
            retList.add(paramId);
        }
        return retList;
    }

    private static String timeGen() {
        return System.currentTimeMillis() + "";
    }

    /**
     * 获得token创建日期
    * @param  token
     * @date  2019/12/6 14:35 祝展
     */
    public Date getTokenGenTime(String token){
        String timeStr = token.substring(1+ 1 , 1+ 1 + 13);
        Long timeLong = Long.valueOf(timeStr);
        return new Date(timeLong);
    }

    public static String uuidGen() {
        String originUUID = UUID.randomUUID().toString().replace("-", "");
        return originUUID.toUpperCase(Locale.CHINA);
    }

    private static String userIdGen(Long userId) {
        String userIdStr = String.valueOf(userId == null ? 0 : userId);
        return userIdStr;
    }

    private static String randomString(int length) {
        if (length <= 0) {
            return "";
        }
        Random r = new Random();
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int index = r.nextInt(strGroup.length());
            buffer.append(strGroup.charAt(index));
        }
        return buffer.toString().toUpperCase(Locale.CHINA);
    }

	/**
	 * @author zhangxj
	 * @Description
	 * 获取oauth生成的token的唯一值tokenId
	 * @since 1.0
	 * @version 1.0
	 * @CreateTime 2020/5/13 17:33
	 * @params
	 * @return
	 **/
	public static String extractOauthTokenKey(String value) {
		if (value == null) {
			return null;
		}
		MessageDigest digest;
		try {
			digest = MessageDigest.getInstance("MD5");
		}
		catch (NoSuchAlgorithmException e) {
			return null;
		}
		try {
			byte[] bytes = digest.digest(value.getBytes("UTF-8"));
			return String.format("%032x", new BigInteger(1, bytes));
		}
		catch (UnsupportedEncodingException e) {
			return null;
		}
	}

    public static void main(String[] args) {
        String token = TokenGenerator.createToken(1L,1L);
        System.out.println(token.length());
        System.out.println(token);
        List<Long> idList= TokenGenerator.analysisToken(token);
        System.out.println(JSON.toJSONString(idList));
    }
}
